package com.starlight.flower_server.infrastructure.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.starlight.flower_server.domain.item.cqrs.ItemPageQuery;
import com.starlight.flower_server.infrastructure.entity.Item;
import com.starlight.flower_server.infrastructure.mapper.ItemMapper;
import com.starlight.flower_server.infrastructure.util.CurrentUserInfoUtils;
import com.starlight.flower_server.infrastructure.util.PageUtils;
import com.starlight.flower_server.infrastructure.repository.ItemRepository;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author yfy2001
 * @date 2023/4/18 8:16
 */
@Repository
public class ItemRepositoryImpl implements ItemRepository {

    @Resource
    private ItemMapper itemMapper;

    @Override
    public Item queryDetail(Long id) {
        return itemMapper.selectById(id);
    }

    @Override
    public Integer logicDelete(Long id) {
        return itemMapper.deleteById(id);
    }

    @Override
    public Integer insert(Item item) {
        String operator= CurrentUserInfoUtils.get("username");
        item.setCreator(operator);
        item.setModifier(operator);
        item.setCreated(new Date());
        item.setModified(new Date());
        item.setIsDeleted(0);
        return itemMapper.insert(item);
    }

    @Override
    public Integer modify(Item item) {
        String modifier= CurrentUserInfoUtils.get("username");
        item.setModifier(modifier);
        item.setModified(new Date());
        return itemMapper.updateById(item);
    }

    /**
     * 自动更新库存
     * @param item
     * @return
     */
    @Override
    public Integer autoModifyStock(Item item) {
        item.setModifier("SYSTEM");
        item.setModified(new Date());
        return itemMapper.updateById(item);
    }


    @Override
    public Map<Long, Item> queryMap(List<Long> itemIdList) {
        if (Objects.isNull(itemIdList) || itemIdList.isEmpty()){
            return Collections.emptyMap();
        }
        QueryWrapper<Item> query = new QueryWrapper<>();
        query.lambda().in(Item::getId,itemIdList);
        List<Item> list = itemMapper.selectList(query);
        return list.stream().collect(Collectors.toMap(Item::getId, v->v,(v1, v2)->v2));
    }

    @Override
    public IPage<Item> queryPage(ItemPageQuery query) {
        QueryWrapper<Item> queryWrapper= PageUtils.createOrderQuery(query);
        queryWrapper.lambda()
                .isNotNull(Item::getId)
                .eq(Objects.nonNull(query.getId()), Item::getId,query.getId())
                .like(Objects.nonNull(query.getName()),Item::getName,query.getName())
                .le(Objects.nonNull(query.getPrice()),Item::getPrice,query.getPrice())
                .ge(Objects.nonNull(query.getStock()),Item::getStock,query.getStock());
        return itemMapper.selectPage(PageUtils.startPage(query),queryWrapper);
    }

    @Override
    public IPage<Item> queryPageByCategory(List<Long> categoryIdList,ItemPageQuery query) {
        QueryWrapper<Item> queryWrapper= PageUtils.createOrderQuery(query);
        queryWrapper.lambda()
                .isNotNull(Item::getId)
                .eq(Objects.nonNull(query.getId()), Item::getId,query.getId())
                .like(Objects.nonNull(query.getName()),Item::getName,query.getName())
                .le(Objects.nonNull(query.getPrice()),Item::getPrice,query.getPrice())
                .ge(Objects.nonNull(query.getStock()),Item::getStock,query.getStock())
                .in(Objects.nonNull(categoryIdList),Item::getItemCategoryId,categoryIdList);
        return itemMapper.selectPage(PageUtils.startPage(query),queryWrapper);
    }

    @Override
    public List<Item> queryAll() {
        return itemMapper.selectList(new LambdaQueryWrapper<Item>()
                .isNotNull(Item::getId));
    }

    @Override
    public Long queryTotalCount() {
        return itemMapper.selectCount(new LambdaQueryWrapper<Item>()
                .isNotNull(Item::getId));
    }

    @Override
    public List<Item> queryRandom(Integer count) {
        return itemMapper.selectList(new LambdaQueryWrapper<Item>()
                .isNotNull(Item::getId)
                .last(String.format("order by rand() limit %d",count)));
    }

    @Override
    public List<Item> queryByCategory(List<Long> itemCategoryIdList) {
        return itemMapper.selectList(new LambdaQueryWrapper<Item>()
                .in(Item::getItemCategoryId,itemCategoryIdList));
    }
}
